home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / gpp-1_42.lha / g++-1.42.0 / collect.c < prev    next >
C/C++ Source or Header  |  1991-10-19  |  17KB  |  715 lines

  1. /* Output tables which say what global initializers need
  2.    to be called at program startup, and what global destructors
  3.    need to be called at program termination, for GNU C++ compiler.
  4.    Copyright (C) 1987 Free Software Foundation, Inc.
  5.    Hacked by Michael Tiemann (tiemann@mcc.com)
  6.    COFF Changes by Dirk Grunwald (grunwald@flute.cs.uiuc.edu)
  7.  
  8. This file is part of GNU CC.
  9.  
  10. GNU CC is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY.  No author or distributor
  12. accepts responsibility to anyone for the consequences of using it
  13. or for whether it serves any particular purpose or works at all,
  14. unless he says so in writing.  Refer to the GNU CC General Public
  15. License for full details.
  16.  
  17. Everyone is granted permission to copy, modify and redistribute
  18. GNU CC, but only under the conditions described in the
  19. GNU CC General Public License.   A copy of this license is
  20. supposed to have been given to you along with GNU CC so you
  21. can know your rights and responsibilities.  It should be in a
  22. file named COPYING.  Among other things, the copyright notice
  23. and this notice must be preserved on all copies.  */
  24.  
  25.  
  26. /* This file contains all the code needed for the program `collect'.
  27.  
  28.    `collect' is run on all object files that are processed
  29.    by GNU C++, to create a list of all the file-level
  30.    initialization and destruction that need to be performed.
  31.    It generates an assembly file which holds the tables
  32.    which are walked by the global init and delete routines.
  33.    The format of the tables are an integer length,
  34.    followed by the list of function pointers for the
  35.    routines to be called.
  36.  
  37.    Constructors are called in the order they are laid out
  38.    in the table.  Destructors are called in the reverse order
  39.    of the way they lie in the table.  */
  40.  
  41. #include "config.h"
  42. int target_flags;    /* satisfy dependency in config.h */
  43.  
  44. #ifndef USE_COLLECT
  45. main()
  46. {
  47.   exit(0);
  48. }
  49.  
  50. #else
  51.  
  52.  
  53. #include <sys/types.h>
  54. #include <sys/stat.h>
  55.  
  56. #include <stdio.h>
  57. #include <a.out.h>
  58. #include <ar.h>
  59.  
  60. #ifdef UMAX
  61. #include <sgs.h>
  62. #endif
  63.  
  64. /*
  65.  *    Define various output routines in terms on ASM_INT_OP,
  66.  *    which should be defined in config.h -- if it's not, add it
  67.  *    as the marker used to allocate an int on your architecture.
  68.  */
  69. #ifdef i386
  70. #define ASM_INT_OP    ASM_LONG
  71. #define NO_UNDERSCORES 1
  72. #endif
  73.  
  74. #ifdef mips
  75. #define NO_UNDERSCORES 1
  76. /*
  77.  * provide stubs for various things in tm-mips.h
  78.  */
  79. enum mips_sections cur_section;
  80. int inside_function = 0;
  81. int num_source_filenames = 0;
  82. void print_options() { return; };
  83. void data_section() { return; };
  84. FILE *asm_out_text_file, *asm_out_data_file;
  85. void pfatal_with_name(str)
  86. char *str;
  87. {
  88.   fprintf(stderr,"collect: %s\n", str);
  89.   exit(1);
  90. }
  91. void pic_label_is_global () {return;};
  92. #endif
  93.  
  94. #ifndef ASM_OUTPUT_INT_CONST
  95. #define ASM_OUTPUT_INT_CONST(FILE,VALUE)    \
  96.   fprintf(FILE,"\t%s %d\n", ASM_INT_OP, VALUE)
  97. #endif
  98.  
  99. #ifndef ASM_OUTPUT_LABELREF_AS_INT
  100. #define ASM_OUTPUT_LABELREF_AS_INT(FILE,NAME)    \
  101.   (fprintf(FILE,"\t%s", ASM_INT_OP), \
  102.    ASM_OUTPUT_LABELREF(FILE,NAME), \
  103.    fprintf(FILE,"\n"))
  104. #endif
  105.  
  106. #ifndef ASM_OUTPUT_PTR_INT_SUM
  107. #define ASM_OUTPUT_PTR_INT_SUM(FILE,NAME,VALUE)    \
  108.   (fprintf(FILE,"\t%s", ASM_INT_OP), \
  109.    ASM_OUTPUT_LABELREF(FILE,NAME), \
  110.    fprintf(FILE,"+%d\n", VALUE))
  111. #endif
  112.  
  113. #ifndef ASM_OUTPUT_SOURCE_FILENAME
  114. #define ASM_OUTPUT_SOURCE_FILENAME(FILE,NAME)\
  115.   fprintf (FILE, "\t.file\t\"%s\"\n", NAME);
  116. #endif
  117.  
  118. extern int xmalloc ();
  119. extern void free ();
  120.  
  121. #ifndef CTOR_TABLE_NAME
  122. #define CTOR_TABLE_NAME "__CTOR_LIST__"
  123. #endif
  124.  
  125. #ifndef DTOR_TABLE_NAME
  126. #define DTOR_TABLE_NAME "__DTOR_LIST__"
  127. #endif
  128.  
  129. /*    Define or undef this in your config.h. Should be defined for
  130.  *    MIPS & Sun-386i.
  131.  */
  132.  
  133. #ifdef NO_UNDERSCORES
  134. #  ifndef CTOR_DTOR_MARKER_NAME
  135. #    ifndef NO_DOLLAR_IN_LABEL
  136. #      define CTOR_DTOR_MARKER_NAME "_GLOBAL_$"
  137. #    else
  138. #      define CTOR_DTOR_MARKER_NAME "_GLOBAL_."
  139. #    endif
  140. #    define CTOR_DTOR_MARKER_LENGTH 9
  141. #    define CTOR_DTOR_MARKER_OFFSET 0
  142. #  endif
  143. #else
  144. #  ifndef CTOR_DTOR_MARKER_NAME
  145. #    ifndef NO_DOLLAR_IN_LABEL
  146. #      define CTOR_DTOR_MARKER_NAME "__GLOBAL_$"
  147. #    else
  148. #      define CTOR_DTOR_MARKER_NAME "__GLOBAL_."
  149. #    endif
  150. #    define CTOR_DTOR_MARKER_LENGTH 10
  151. #    define CTOR_DTOR_MARKER_OFFSET 1
  152. #  endif
  153. #endif
  154.  
  155. enum error_code { OK, BAD_MAGIC, NO_NAMELIST,
  156.           FOPEN_ERROR, FREAD_ERROR, FWRITE_ERROR,
  157.           RANDOM_ERROR, };
  158.  
  159. enum error_code process ();
  160. enum error_code process_a (), process_o ();
  161. enum error_code output_ctor_dtor_table ();
  162. void assemble_name ();
  163.  
  164. /* Files for holding the assembly code for table of constructor
  165.    function pointer addresses and list of destructor
  166.    function pointer addresses.  */
  167. static FILE *outfile;
  168.  
  169. /* Default outfile name, or take name from argv with -o option.  */
  170. static char *outfile_name = "a.out";
  171.  
  172. /* For compatibility with toplev.c and tm-sun386.h  */
  173. char *dump_base_name;
  174. int optimize = 0;
  175. char *language_string = "GNU C++";
  176. char *main_input_filename;
  177.  
  178. /*
  179.  * The list of constructors & destructors. We process all files & then
  180.  * spit these out in output_ctor_dtor_table(), because we need to know
  181.  *  the length of the list.
  182.  */
  183.  
  184. struct ctor_dtor_list_elem
  185. {
  186.   struct ctor_dtor_list_elem *next;
  187.   char *name;
  188. } *dtor_chain, *ctor_chain;
  189.  
  190. int dtor_chain_length = 0;
  191. int ctor_chain_length = 0;
  192.  
  193. main (argc, argv)
  194.      int argc;
  195.      char *argv[];
  196. {
  197.   int i, nerrs = 0;
  198.   enum error_code code;
  199.   FILE *fp;
  200.  
  201.   if (argc > 2 && !strcmp (argv[1], "-o"))
  202.     {
  203.       outfile_name = argv[2];
  204.       i = 3;
  205.     }
  206.   else
  207.     i = 1;
  208.  
  209.   if ((outfile = fopen (outfile_name, "w")) == NULL)
  210.     {
  211.       perror ("collect");
  212.       exit (-1);
  213.     }
  214.  
  215.   dump_base_name = main_input_filename = outfile_name;
  216.   for (; i < argc; i++)
  217.     {
  218.       char buf[80];
  219.  
  220.       /* This is a library, skip it.  */
  221.       if (argv[i][0] == '-' && argv[i][1] == 'l')
  222.     continue;
  223.  
  224.       if ((fp = fopen (argv[i], "r")) == NULL)
  225.     {
  226.       sprintf (buf, "collect `%s'", argv[i]);
  227.       perror (buf);
  228.       exit (-1);
  229.     }
  230.  
  231.       switch (code = process (fp, argv[i]))
  232.     {
  233.     case OK:
  234.       break;
  235.  
  236.     case BAD_MAGIC:
  237.       fprintf (stderr, "file `%s' has a bad magic number for collect\n",
  238.            argv[i]);
  239.       exit (-1);
  240.  
  241.     case NO_NAMELIST:
  242.       fprintf (stderr, "file `%s' has a no namelist for collect\n",
  243.            argv[i]);
  244.       exit (-1);
  245.  
  246.     case RANDOM_ERROR:
  247.       fprintf (stderr, "random error while processing file `%s':\n",
  248.            argv[i]);
  249.       perror ("collect");
  250.       exit (-1);
  251.  
  252.     case FOPEN_ERROR:
  253.       fprintf (stderr, "fopen(3S) error while processing file `%s' in collect\n",
  254.            argv[i]);
  255.       exit (-1);
  256.  
  257.     case FREAD_ERROR:
  258.       fprintf (stderr, "fread(3S) error while processing file `%s' in collect\n",
  259.            argv[i]);
  260.       exit (-1);
  261.  
  262.     case FWRITE_ERROR:
  263.       fprintf (stderr, "fwrite(3S) error while processing file `%s' in collect\n",
  264.            argv[i]);
  265.       exit (-1);
  266.  
  267.     default:
  268.       abort ();
  269.     }
  270.  
  271.       fclose (fp);
  272.  
  273.     }
  274.  
  275.   switch (code = output_ctor_dtor_table ())
  276.     {
  277.     case OK:
  278.       fclose (outfile);
  279.       exit (0);
  280.     case FREAD_ERROR:
  281.       perror ("fread(3S) failed in collect, at end");
  282.       break;
  283.     case FWRITE_ERROR:
  284.       perror ("fwrite(3S) failed in collect, at end");
  285.       break;
  286.     case FOPEN_ERROR:
  287.       perror ("fopen(3S) failed in collect, at end");
  288.       break;
  289.     case RANDOM_ERROR:
  290.       fprintf (stderr, "random error in collect, at end");
  291.       break;
  292.     }
  293.   exit (-1);
  294. }
  295.  
  296. void
  297.   add_ctor_dtor_elem(symbol_name)
  298. char *symbol_name;
  299. {
  300.   /*
  301.    *    In EXTENDED_COFF systems, it's possible to
  302.    *    have multiple occurances of symbols ( or so it
  303.    *    appears) in the symbol table. Sooo, we scan to
  304.    *    eliminate duplicate entries. This can never hurt,
  305.    *    and helps EXTENDED_COFF.
  306.    */
  307.   int exists;
  308.   int is_ctor = (symbol_name[CTOR_DTOR_MARKER_LENGTH] == 'I');
  309.   
  310.   struct ctor_dtor_list_elem *p
  311.     = ((is_ctor) ? ctor_chain : dtor_chain);
  312.   
  313.   exists = 0;
  314.   while (p) {
  315.     if (strcmp( symbol_name, p -> name ) == 0 ) {
  316.       exists = 1;
  317.       break;
  318.     }
  319.     p = p -> next;
  320.   }
  321.   if ( ! exists ) {
  322.     
  323.     struct ctor_dtor_list_elem *new = (struct ctor_dtor_list_elem *)
  324.       xmalloc(sizeof(struct ctor_dtor_list_elem));
  325.     
  326.     new->name = (char *)xmalloc (strlen (symbol_name)
  327.                  + CTOR_DTOR_MARKER_OFFSET + 2);
  328.     
  329.     strcpy(new -> name, symbol_name + CTOR_DTOR_MARKER_OFFSET);
  330.     
  331.     if ( is_ctor ) {
  332.       new -> next = ctor_chain;
  333.       ctor_chain = new;
  334.       ctor_chain_length++;
  335.     }
  336.     else {
  337.       new->next = dtor_chain;
  338.       dtor_chain = new;
  339.       dtor_chain_length++;
  340.     }
  341.   }
  342. }
  343.  
  344.  
  345. enum error_code
  346. output_ctor_dtor_table ()
  347. {
  348.   int dtor_offset;
  349.  
  350.   /* Write out the CTOR tabel */
  351.   ASM_FILE_START(outfile);
  352.  
  353. #ifdef EXTENDED_COFF
  354.   fprintf (outfile, "%s\n", SDATA_SECTION_ASM_OP);
  355. #else
  356.   fprintf (outfile, "%s\n", DATA_SECTION_ASM_OP);
  357. #endif
  358.   ASM_GLOBALIZE_LABEL (outfile, CTOR_TABLE_NAME);
  359.   ASM_OUTPUT_LABEL (outfile, CTOR_TABLE_NAME);
  360.   ASM_OUTPUT_INT_CONST(outfile,ctor_chain_length);
  361.   while ( ctor_chain ) {
  362.     ASM_OUTPUT_LABELREF_AS_INT (outfile, ctor_chain->name);
  363.     ctor_chain = ctor_chain -> next;
  364.   }
  365.   /* NULL-terminate the list of constructors.  -- not needed, but keep it */
  366.   ASM_OUTPUT_INT_CONST (outfile, 0);
  367.  
  368.   /*
  369.    * Now, lay out the destructors
  370.    */
  371.  
  372. #ifdef EXTENDED_COFF
  373.   fprintf (outfile, "%s\n", SDATA_SECTION_ASM_OP);
  374. #else
  375.   fprintf (outfile, "%s\n", DATA_SECTION_ASM_OP);
  376. #endif
  377.   ASM_GLOBALIZE_LABEL (outfile, DTOR_TABLE_NAME);
  378.   ASM_OUTPUT_LABEL (outfile, DTOR_TABLE_NAME);
  379.   ASM_OUTPUT_INT_CONST(outfile,dtor_chain_length);
  380.   while (dtor_chain)
  381.     {
  382.       ASM_OUTPUT_LABELREF_AS_INT (outfile, dtor_chain->name);
  383.       dtor_chain = dtor_chain->next;
  384.     }
  385.   ASM_OUTPUT_INT_CONST (outfile, 0);
  386.   ASM_OUTPUT_INT_CONST (outfile, 0);
  387.  
  388.   fclose (outfile);
  389.   return OK;
  390. }
  391.  
  392.  
  393. /*****************************************************************************
  394.  *    
  395.  *        COFF & EXTENDED COFF
  396.  *    
  397.  ****************************************************************************/
  398. #if defined(COFF) || defined(EXTENDED_COFF)
  399.  
  400. #include <ldfcn.h>
  401.  
  402. #if defined(EXTENDED_COFF)
  403. #   define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax+SYMHEADER(X).iextMax)
  404. #   define GCC_SYMENT SYMR
  405. #   define GCC_OK_SYMBOL(X) ((X).st == stProc &&  (X).sc == scText)
  406. #   define GCC_SYMINC(X) (1)
  407. #else
  408. #   define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
  409. #   define GCC_SYMENT SYMENT
  410. #ifndef UNUSUAL_COFF_DEFINITION
  411. #   define GCC_OK_SYMBOL(X) (!(((X).n_type & N_TMASK) != (DT_NON << N_BTSHFT)))
  412. #else
  413. #   define GCC_OK_SYMBOL(X) ((X).n_scnum == 1 && (X).n_sclass == C_EXT)
  414. #endif
  415. #   define GCC_SYMINC(X) ((X).n_numaux+1)
  416. #endif
  417.  
  418. enum error_code
  419.   process (fp, filename)
  420. FILE *fp;
  421. char *filename;
  422. {
  423.   LDFILE *ldptr = NULL;
  424.   do {
  425.     if ((ldptr = ldopen(filename, ldptr)) != NULL ) {
  426.       
  427.       if (!ISCOFF( HEADER(ldptr).f_magic ) ) {
  428.     return BAD_MAGIC;
  429.       }
  430.       else {
  431.     
  432.     int symbols = GCC_SYMBOLS(ldptr);
  433.     int symindex;
  434.     
  435.     for (symindex = 0;
  436.          symindex < symbols;
  437.          ) {
  438.       
  439.       GCC_SYMENT symbol;
  440.       
  441.       char *symbol_name;
  442.       extern char *ldgetname();
  443.       int returnCode;
  444.       
  445.       returnCode = ldtbread(ldptr, symindex, &symbol);
  446.       
  447.       if ( returnCode <= 0 ) {
  448.         break;
  449.       }
  450.       
  451.       symindex += GCC_SYMINC(symbol);
  452.       
  453.       if (! GCC_OK_SYMBOL(symbol)) continue;
  454.       symbol_name = ldgetname(ldptr, &symbol);
  455.       
  456.       /* Check to see if we have a CTOR/DTOR marker  */
  457.  
  458.       if (! strncmp (CTOR_DTOR_MARKER_NAME, symbol_name,
  459.              CTOR_DTOR_MARKER_LENGTH))
  460.         add_ctor_dtor_elem(symbol_name);
  461.     }
  462.       }
  463.     }
  464.     else {
  465.       return( RANDOM_ERROR );
  466.     }
  467.   } while ( ldclose(ldptr) == FAILURE ) ;
  468.   return ( OK );
  469. }
  470.  
  471. /****** taken from sdbout.c ******/
  472.  
  473.  
  474. /* Tell the assembler the source file name.
  475.    On systems that use SDB, this is done whether or not -g,
  476.    so it is called by ASM_FILE_START.
  477.  
  478.    ASM_FILE is the assembler code output file,
  479.    INPUT_NAME is the name of the main input file.  */
  480.  
  481. /* void */
  482. sdbout_filename (asm_file, input_name)
  483.      FILE *asm_file;
  484.      char *input_name;
  485. {
  486.   int len = strlen (input_name);
  487.   char *na = input_name + len;
  488.  
  489.   /* NA gets INPUT_NAME sans directory names.  */
  490.   while (na > input_name)
  491.     {
  492.       if (na[-1] == '/')
  493.     break;
  494.       na--;
  495.     }
  496.  
  497.   ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);
  498. }
  499.  
  500. #else
  501.  
  502. /*****************************************************************************
  503.  *    
  504.  *        BSD SYMBOL TABLES
  505.  *    
  506.  *****************************************************************************/
  507.  
  508. /* Figure out the type of file we need to process.
  509.    Currently, only .o and .a formats are acceptable.  */
  510. enum error_code
  511. process (fp, filename)
  512.      FILE *fp;
  513.      char *filename;
  514. {
  515.   struct stat file_stat;
  516.   union
  517.     {
  518.       char ar_form[SARMAG];
  519.       struct exec a_out_form;
  520.     } header;
  521.   int size;
  522.  
  523.   if (fstat (fp->_file, &file_stat))
  524.     return RANDOM_ERROR;
  525.  
  526.   size = file_stat.st_size;
  527.  
  528.   if (fread (header.ar_form, SARMAG, 1, fp) < 1)
  529.     return RANDOM_ERROR;
  530.  
  531.   if (strncmp (ARMAG, header.ar_form, SARMAG))
  532.     {
  533.       fseek (fp, 0, 0);
  534.       if (fread (&header.a_out_form, sizeof (struct exec), 1, fp) < 1)
  535.     return RANDOM_ERROR;
  536.  
  537.       if (N_BADMAG (header.a_out_form))
  538.     return BAD_MAGIC;
  539.  
  540.       return process_o (fp, &header.a_out_form, size);
  541.     }
  542.   return process_a (fp);
  543. }
  544.  
  545. enum error_code
  546. process_o (fp, header, size)
  547.      FILE *fp;
  548.      struct exec *header;
  549.      int size;
  550. {
  551.   int symoff, symend;
  552. #ifndef hp9000s300
  553.   struct nlist *nelem, *nelems, *nend;
  554.   char *strtab;
  555. #else
  556.   struct nlist_ *nelem, *nelems, *nend;
  557. #endif /* hp9000s300 */
  558.  
  559.   if (N_BADMAG (*header))
  560.     return BAD_MAGIC;
  561.  
  562. #ifndef hp9000s300
  563.   symoff = N_SYMOFF (*header);
  564.   symend = N_STROFF (*header);
  565. #else
  566.   symoff = LESYM_OFFSET (*header);
  567.   symend = DNTT_OFFSET (*header);
  568. #endif /* hp9000s300 */
  569.   if (symoff == symend)
  570.     return NO_NAMELIST;
  571.   fseek (fp, symoff - sizeof (struct exec), 1);
  572. #ifndef hp9000s300
  573.   nelems = (struct nlist *)alloca (symend - symoff);
  574. #else
  575.   nelems = (struct nlist_ *)alloca (symend - symoff);
  576. #endif /* hp9000s300 */
  577.   if (fread (nelems, sizeof (char), symend - symoff, fp) < symend - symoff)
  578.     return FREAD_ERROR;
  579.  
  580. #ifndef hp9000s300
  581.   strtab = (char *)alloca ((char *)size - (char *)symend);
  582.   if (fread (strtab, sizeof (char), (char *)size - (char *)symend, fp)
  583.       < ((char *)size - (char *)symend) * sizeof (char))
  584.     return FREAD_ERROR;
  585.  
  586.   nend = (struct nlist *)((char *)nelems + symend - symoff);
  587.   for (nelem = nelems; nelem < nend; nelem++)
  588. #else
  589.   nend = (struct nlist_ *)((char *)nelems + symend - symoff);
  590.   for (nelem = nelems; nelem < nend; )
  591. #endif /* hp9000s300 */
  592.     {
  593. #ifndef hp9000s300
  594.       int strindex = nelem->n_un.n_strx;
  595. #else
  596.       int symlen = nelem->n_length;
  597.       char p[255];
  598.       memcpy(p, (char *) (++nelem), symlen);
  599.       p[symlen]='\0';
  600.      
  601.       /* printf("'%s'\n",p);   */
  602. #endif /* hp9000s300 */
  603.  
  604. #ifndef hp9000s300
  605.       if (strindex)
  606. #else
  607.       nelem   = (struct nlist_ *)((char *)nelem + symlen);
  608.       
  609.       if (symlen)
  610. #endif /* hp9000s300 */
  611.     {
  612. #ifndef hp9000s300
  613.       char *p = strtab+strindex;
  614. #endif /* hp9000s300 */
  615.  
  616.       if (! strncmp ("__GLOBAL_$", p, 10))
  617.         add_ctor_dtor_elem(p);
  618.     }
  619.     }
  620.   return OK;
  621. }
  622.  
  623. enum error_code
  624. process_a (fp)
  625.      FILE *fp;
  626. {
  627.   struct ar_hdr header;
  628.   struct exec exec_header;
  629.   int size;
  630.   enum error_code code;
  631.  
  632.   while (! feof (fp))
  633.     {
  634.       char c;
  635. #ifdef hp9000s300
  636.       int curpos;
  637. #endif /* hp9000s300 */
  638.  
  639.       if (fread (&header, sizeof (struct ar_hdr), 1, fp) < 1)
  640.     return RANDOM_ERROR;
  641.  
  642.       size = atoi (header.ar_size);
  643. #ifdef hp9000s300
  644.       curpos = ftell(fp);
  645. #endif /* hp9000s300 */
  646.  
  647. #ifndef hp9000s300
  648.       if (fread (&exec_header, sizeof (struct exec), 1, fp) < 1)
  649.     return RANDOM_ERROR;
  650. #else
  651.       /* if the name starts with /, it's an index file */
  652.       if (header.ar_name[0] != '/') {
  653.       
  654.         if (fread (&exec_header, sizeof (struct exec), 1, fp) < 1)
  655.       return RANDOM_ERROR;
  656. #endif /* hp9000s300 */
  657.  
  658.       code = process_o (fp, &exec_header, size);
  659.       if (code != OK)
  660.     return code;
  661. #ifdef hp9000s300
  662.       } 
  663.       
  664.       if (fseek(fp,(long) curpos + size,0))
  665.     return RANDOM_ERROR;
  666. #endif /* hp9000s300 */
  667.       if ((c = getc (fp)) == '\n')
  668.     ;
  669.       else
  670.     ungetc (c, fp);
  671.       c = getc (fp);
  672.       if (c != EOF)
  673.     ungetc (c, fp);
  674.     }
  675.   return OK;
  676. }
  677. #endif
  678.  
  679. /* Output to FILE a reference to the assembler name of a C-level name NAME.
  680.    If NAME starts with a *, the rest of NAME is output verbatim.
  681.    Otherwise NAME is transformed in an implementation-defined way
  682.    (usually by the addition of an underscore).
  683.    Many macros in the tm file are defined to call this function.
  684.  
  685.    Swiped from `varasm.c'  */
  686.  
  687. void
  688. assemble_name (file, name)
  689.      FILE *file;
  690.      char *name;
  691. {
  692.   if (name[0] == '*')
  693.     fputs (&name[1], file);
  694.   else
  695. #ifdef NO_UNDERSCORES
  696.     fprintf (file, "%s", name);
  697. #else
  698.     fprintf (file, "_%s", name);
  699. #endif
  700. }
  701.  
  702. int
  703. xmalloc (size)
  704.      int size;
  705. {
  706.   int result = malloc (size);
  707.   if (! result)
  708.     {
  709.       fprintf (stderr, "Virtual memory exhausted\n");
  710.       exit (-1);
  711.     }
  712.   return result;
  713. }
  714. #endif
  715.